<?php

namespace App\Http\Services;

use App\Http\Model\FinanceDiamond;
use App\Http\Model\GiftStream;
use App\Http\Model\Hint;
use App\Http\Model\Rebate;
use App\Http\Model\System;
use App\Http\Model\User;
use Carbon\Carbon;
use DateInterval;
use DatePeriod;
use DateTime;
use Illuminate\Support\Facades\DB;

class RebateServices extends CommonServices
{
    protected $userModel;
    protected $rebateModel;
    protected $sysModel;
    protected $diamond_model;

    protected $error_log = 'error_rebate';//失败日志

    public function __construct()
    {
        parent::__construct();
        $this->userModel = new User();
        $this->rebateModel = new Rebate();
        $this->sysModel = new System();
        $this->diamond_model = new FinanceDiamond();
    }

    //获取用户返利值
    public function getUserDDvalue($userId){
        $code = Hint::SUCCESS;
        $msg = "ok";
        $data = [];
        do{
            //获取用户基本信息
            $userInfo = $this->userModel->get_user($userId);

            if(empty($userInfo)){
                $code = Hint::LOGIN_OUT;
                break;
            }

            //获取后台配置门槛
            $sysConfig = $this->sysModel->get_config();
            $rebateConfig = isset($sysConfig['dd_rebate_config']) ? json_decode($sysConfig['dd_rebate_config']['value'],true) : [];
            if(empty($rebateConfig)){
                $code = Hint::ERR_NORMAL;
                $msg = '活动暂未开始';
                break;
            }
            $ddLevel = $rebateConfig['ddLevel'];//DD值门槛
            $ddRate = $rebateConfig['ddRate'];//DD值钻石反比百分
            // 西西
            $rule = '1.甜枕惊喜福利，累计DD值领取钻石。'.PHP_EOL.
                    '2.根据用户在平台的活跃行为，免费赠送“DD值”。'.PHP_EOL.
                    '3.每周累计达到'.$ddLevel.'  DD值，次周周一领取钻石奖励（周一24点前未领取视为自愿放弃，不可补发）。'.PHP_EOL.
                    '4.奖励钻石为上周DD值的'.$ddRate.'%。'.PHP_EOL.
                    '5.本活动最终解释权为甜枕所有，如遇任何违规经查证，官方有权取消违规账号奖励，且对账号进行封禁处理。'
            ;
            //活动开始时间/结束时间
            $start = $rebateConfig['start_time'];
            $end = $rebateConfig['end_time'];
            $dateCount = $this->getStartAndEndTimeByDate($start, $end);
            //本周开始结束时间
            $todayWeekStart = Carbon::now()->startOfWeek()->toDateString();
            $todayWeekEnd = Carbon::now()->endOfWeek()->toDateString();
            $now = Carbon::now()->toDateTimeString();
            if(isset($dateCount[$todayWeekStart]) && $todayWeekStart < $end && $now <= $end){
                $nowCount = $dateCount[$todayWeekStart]['count'];
                $nowCount = numberToChinese($nowCount);
                //期数
                $nowRoundStr = '第'.$nowCount.'期:'.date('n.d',strtotime($todayWeekStart)).'-'.date('n.d',strtotime($todayWeekEnd));
            }else{
                $nowRoundStr = '活动已结束';
            }

            $thisWeekDDvalue = 0;//本周dd值
            $thisWeeKDiamond = 0;//本周钻石数
            $lastWeekDDvalue = 0;//上周dd值
            $lastWeekDiamond = 0;//上周钻石数

            //查看时间是否是周一
            $date = Carbon::createFromFormat('Y-m-d', Carbon::today()->toDateString());
            $isMonday = $date->isMonday();
            $status = 3;
            $buttonMsg = [
                '0' => '领取钻石',
                '1' => '已领取',
                '2' => '领取钻石',
                '3' => '未达标'
            ];

            //获取用户本周的返利值
            $startWeek = Carbon::now()->startOfWeek()->toDateTimeString();//本周开始
            $endWeek = Carbon::now()->endOfWeek()->toDateTimeString();//本周结束

            $now = Carbon::now()->toDateTimeString();//现在时间
            if($now <= $end && $now >= $start){//在活动期间内
                $allBagValue = $this->rebateModel->getAllBagData($userId, $startWeek, $endWeek);
                $allBagValue = empty($allBagValue['total']) ? 0 : $allBagValue['total'];
                $allColorGiftValue = $this->rebateModel->getAllColorGiftData($userId, $startWeek, $endWeek);
                $allColorGiftValue = empty($allColorGiftValue['total']) ? 0 : $allColorGiftValue['total'];
                $thisWeekTotalDiamond = $allBagValue + $allColorGiftValue;
                //本周dd值
                $thisWeekDDvalue = $thisWeekTotalDiamond;
                //预估本周领取钻石数  门槛达到后台配置10000才算
                if($thisWeekTotalDiamond >= $ddLevel){
                    $thisWeeKDiamond = intval($thisWeekDDvalue * ($ddRate/100));
                }
            } 

            //获取用户上周返利值
            $lastWeekStart = Carbon::now()->subWeek()->startOfWeek()->toDateString();//上周开始
            $lastWeekEnd = Carbon::now()->subWeek()->endOfWeek()->toDateString();//上周结束

            $lastUserInfo = $this->rebateModel->getLastWeek($userId, $lastWeekStart, $lastWeekEnd);
            if(!empty($lastUserInfo)){
                $lastWeekDDvalue = $lastUserInfo['dd_value'];
                $lastWeekDiamond = $lastUserInfo['award_diamond'];
                $status = $lastUserInfo['status'];
            }

            //非周一时候显示置灰
            if(!$isMonday){
                $status = 2;
            }

            $buttonStatus = $status==0 ? 1 : 0;
            
            $data = [
                'thisWeekDDvalue' => (int)$thisWeekDDvalue,
                'thisWeeKDaimond' => $thisWeeKDiamond,
                'lastWeekDDvalue' => $lastWeekDDvalue,
                'lastWeekDiamond' => $lastWeekDiamond,
                'lastWeekDataId' => empty($lastUserInfo['id']) ? 0 : $lastUserInfo['id'],
                'button_status' => $buttonStatus,
                'button_text' => $buttonMsg[$status],
                'name' => $userInfo['nickname'],
                'image' => $userInfo['images'][0],//头像
                'user_id' => $userInfo['user_id'],
                'uuid' => $userInfo['user_uid'],
                'rule' => $rule,
                'start_time' => $start,
                'end_time' => $end,
                'now_round_str' => $nowRoundStr,
            ];
        }while(false);
        return compact('code','msg','data');
    }

    //领取奖励
    public function sendAward($userId, $dataId){
        $code = Hint::SUCCESS;
        $msg = 'ok';
        $data = [];
        do{
            $redis = redis_lock('send_dd_award'.$userId,3);
            if(!$redis){
                $code = Hint::ERR_NORMAL;
                $msg = '操作太频繁';
                break;
            }
            //获取后台配置门槛
            $sysConfig = $this->sysModel->get_config();
            $rebateConfig = isset($sysConfig['dd_rebate_config']) ? json_decode($sysConfig['dd_rebate_config']['value'],true) : [];
            if(empty($rebateConfig)){
                $code = Hint::ERR_NORMAL;
                $msg = '活动暂未开始';
                break;
            }
            //判断领取时间是否在活动范围内
            $endWeekAddOneDay = Carbon::parse($rebateConfig['end_time'])->addDay(1)->toDateTimeString();//结束后一天
            $now = Carbon::now()->toDateTimeString();
            if($now > $endWeekAddOneDay){
                $code = Hint::ERR_NORMAL;
                $msg = '活动已结束';
                break;
            }
            if($now < $rebateConfig['start_time']){
                $code = Hint::ERR_NORMAL;
                $msg = '活动未开始';
                break;
            }
            //领取日期是否是周一
            $date = Carbon::createFromFormat('Y-m-d', Carbon::today()->toDateString());
            
            //方法判断是否是周一
            $isMonday = $date->isMonday();
            if(!$isMonday){
                $code = Hint::ERR_NORMAL;
                $msg = '领取日期必须是周一';
                break;
            }

            //获取用户基本信息
            $userInfo = $this->userModel->get_user($userId);
            if(empty($userInfo)){
                $code = Hint::LOGIN_OUT;
                break;
            }
            //发放奖励
            $awardInfo = $this->rebateModel->getLastWeekById($dataId);
            if(empty($awardInfo)){
                $code = Hint::ERR_NORMAL;
                $msg = '未达到领取条件';
                break;
            }
            if($awardInfo['status'] == 1){
                $code = Hint::ERR_NORMAL;
                $msg = '已领取';
                break;
            }
            if($awardInfo['status'] == 2){
                $code = Hint::ERR_NORMAL;
                $msg = '已过期';
                break;
            }
            //奖励钻石数
            $sendDiamond = $awardInfo['award_diamond'];
            $config = config('pay');
            $diamond_desc = $config['wallet_change_desc']['diamond_dd_rebate_incr'];
            DB::beginTransaction();
            try{
                $sendStatus = $this->diamond_model->inc($userId, 11, 0, 90, $sendDiamond ,$diamond_desc);
                $update = [
                    'status' => 1,//0=未领取 1=已领取 2=已过期 3=未达标
                ];
                $this->rebateModel->changeData($update,$dataId);
                $data = [
                    'msg' => '成功领取',
                    'diamond' => $sendDiamond
                ];
                DB::commit();
            }catch(\Exception $e){
                $code = Hint::ERR_NORMAL;
                $msg = '领取失败';
                write_log($this->error_log,'ERROR 领取钻石失败',['msg'=>$e->getMessage(),'file'=>$e->getFile(),'update'=>$update]);
                DB::rollBack();
                break;
            }
        }while(false);
        return compact('code','msg','data');
    }

    /**
     * 根据时间范围获取期数
     */
    public function getStartAndEndTimeByDate($startDate, $endDate)
    {
        $start = new DateTime($startDate);
        $end = new DateTime($endDate);
        $end->modify('next sunday'); // 确保结束日期是下一个周日
        $interval = new DateInterval('P7D'); // 每7天为一周
        $period = new DatePeriod($start, $interval, $end);
    
        $groups = [];
        foreach ($period as $k=>$week) {
            $key = $week->format('Y-m-d'); // 周的起始日期作为数组的键
            $groups[$key] = []; // 初始化该周的数组
        }
        $count = 1;
        for ($current = $start; $current <= $end; $current->modify('+1 day')) {
            $day = $current->format('Y-m-d');
            if (isset($groups[$day])) {
                // 当前日期是周的开始日期，将其加入到对应的周数组中
                $groups[$day]['date'] = $current->format('Y-m-d');
                $groups[$day]['count'] = $count;
                $count = $count+1;
            }
        }
    
        return $groups;
    }
}